/**
 * View World.
 *
 * Released under Apache License, Version 2.0.
 */

package bsp.eclair.simplelinechart.viewworld;

public abstract class ViewWorld
{
	public static final int VIEWWORLD_QUARTANT_1 = 1;
	public static final int VIEWWORLD_QUARTANT_2 = 2;
	public static final int VIEWWORLD_QUARTANT_3 = 3;
	public static final int VIEWWORLD_QUARTANT_4 = 4;
	
	protected int mType;
	protected float mWorldXMin, mWorldYMin, mWorldXMax, mWorldYMax;
	protected float mOriginX, mOriginY;
	protected int mViewXMin, mViewYMin, mViewXMax, mViewYMax;
	protected int mLeftPadding, mTopPadding, mRightPadding, mBottomPadding; 
	
	/**
	 * Default constructor.
	 * Create with default world object coordinate values, namely 0 to 1.
	 * View object coordinate values are default, namely 0 to 100.
	 * Origin is at 0,0 of world object.
	 * Padding values are zero.
	 */
	public ViewWorld(int quadrant)
	{
		mType = quadrant;
		
		mWorldXMin = mWorldYMin = 0;
		mWorldXMax = mWorldYMax = 1;
		
		mViewXMin = mViewYMin = 0;
		mViewXMax = mViewYMax = 100;
		
		mOriginX = mOriginY = 0;
		
		mLeftPadding = mTopPadding = mRightPadding = mBottomPadding = 0;
	}
	
	/**
	 * Create with default world object coordinate values, namely 0 to 1.
	 * View object coordinate values are as provided.
	 * Origin is at 0,0 of world object.
	 * Padding values are zero.
	 * 
	 * @param viewStartX
	 * @param viewStartY
	 * @param viewEndX
	 * @param viewEndY
	 */
	public ViewWorld(int quadrant, int viewStartX, int viewStartY, int viewEndX, int viewEndY)
	{
		mType = quadrant;
		
		mWorldXMin = mWorldYMin = 0;
		mWorldXMax = mWorldYMax = 1;
		
		mViewXMin = viewStartX;
		mViewYMin = viewStartY;
		mViewXMax = viewEndX;
		mViewYMax = viewEndY;
		
		mOriginX = mOriginY = 0;
		
		mLeftPadding = mTopPadding = mRightPadding = mBottomPadding = 0;
	}
	
	/**
	 * Create with default view object coordinate values, namely 0 to 100.
	 * World object coordinate values are as provided.
	 * Origin is at 0,0 of world object.
	 * Padding values are zero.
	 * 
	 * @param worldStartX
	 * @param worldStartY
	 * @param worldEndX
	 * @param worldEndY
	 */
	public ViewWorld(int quadrant, float worldStartX, float worldStartY, float worldEndX, float worldEndY)
	{
		mType = quadrant;
		
		mWorldXMin = worldStartX;
		mWorldYMin = worldStartY;
		mWorldXMax = worldEndX;
		mWorldYMax = worldEndY;
		
		mViewXMin = mViewYMin = 0;
		mViewXMax = mViewYMax = 100;
		
		mOriginX = mOriginY = 0;
		
		mLeftPadding = mTopPadding = mRightPadding = mBottomPadding = 0;
	}
	
	/**
	 * Initialize object using coordinate values provided.
	 * Origin is at 0,0 of world object.
	 * Padding values are zero.
	 * 
	 * @param worldStartX
	 * @param worldStartY
	 * @param worldEndX
	 * @param worldEndY
	 * @param viewStartX
	 * @param viewStartY
	 * @param viewEndX
	 * @param viewEndY
	 */
	public ViewWorld(int quadrant, float worldStartX, float worldStartY, float worldEndX, float worldEndY, int viewStartX, int viewStartY, int viewEndX, int viewEndY)
	{
		mType = quadrant;
		
		mWorldXMin = worldStartX;
		mWorldYMin = worldStartY;
		mWorldXMax = worldEndX;
		mWorldYMax = worldEndY;
		
		mViewXMin = viewStartX;
		mViewYMin = viewStartY;
		mViewXMax = viewEndX;
		mViewYMax = viewEndY;
		
		mOriginX = mOriginY = 0;
		
		mLeftPadding = mTopPadding = mRightPadding = mBottomPadding = 0;
	}
	
	/**
	 * Initialize using values provided.
	 * Padding values are zero.
	 * 
	 * @param worldStartX
	 * @param worldStartY
	 * @param worldEndX
	 * @param worldEndY
	 * @param originX
	 * @param originY
	 * @param viewStartX
	 * @param viewStartY
	 * @param viewEndX
	 * @param viewEndY
	 */
	public ViewWorld(int quadrant, float worldStartX, float worldStartY, float worldEndX, float worldEndY, float originX, float originY, int viewStartX, int viewStartY, int viewEndX, int viewEndY)
	{
		mType = quadrant;
		
		mWorldXMin = worldStartX;
		mWorldYMin = worldStartY;
		mWorldXMax = worldEndX;
		mWorldYMax = worldEndY;
		
		mViewXMin = viewStartX;
		mViewYMin = viewStartY;
		mViewXMax = viewEndX;
		mViewYMax = viewEndY;
		
		mOriginX = originX;
		mOriginY = originY;
		
		mLeftPadding = mTopPadding = mRightPadding = mBottomPadding = 0;
	}
	
	/**
	 * Initialize using values provided.
	 * 
	 * @param worldStartX
	 * @param worldStartY
	 * @param worldEndX
	 * @param worldEndY
	 * @param originX
	 * @param originY
	 * @param viewStartX
	 * @param viewStartY
	 * @param viewEndX
	 * @param viewEndY
	 * @param leftPadding
	 * @param topPadding
	 * @param rightPadding
	 * @param bottomPadding
	 */
	public ViewWorld(int quadrant, float worldStartX, float worldStartY, float worldEndX, float worldEndY, float originX, float originY, int viewStartX, int viewStartY, int viewEndX, int viewEndY, int leftPadding, int topPadding, int rightPadding, int bottomPadding)
	{
		mType = quadrant;
		
		mWorldXMin = worldStartX;
		mWorldYMin = worldStartY;
		mWorldXMax = worldEndX;
		mWorldYMax = worldEndY;
		
		mLeftPadding = leftPadding;
		mTopPadding = topPadding;
		mRightPadding = rightPadding;
		mBottomPadding = bottomPadding;
		
		mViewXMin = viewStartX + mLeftPadding;
		mViewYMin = viewStartY + mTopPadding;
		mViewXMax = viewEndX - mRightPadding;
		mViewYMax = viewEndY - mBottomPadding;
		
		mOriginX = originX;
		mOriginY = originY;
	}
	
	/**
	 * Check if the ViewWorld object is of specified type.
	 * 
	 * @param quadrant
	 * @return
	 */
	public boolean isType(int quadrant)
	{
		return mType == quadrant;
	}
	
	/**
	 * Get dimensions of world object.
	 * 
	 * @return
	 */
	public RectFloat getWorldDimensions()
	{
		RectFloat rf = new RectFloat();
		rf.left = mWorldXMin;
		rf.top = mWorldYMin;
		rf.right = mWorldXMax;
		rf.bottom = mWorldYMax;
		
		return rf;
	}
	
	/**
	 * Update the dimensions of the world using absolute values.
	 * 
	 * @param minx
	 * @param miny
	 * @param maxx
	 * @param maxy
	 * @param originX
	 * @param originY
	 */
	public void updateWorldDimensions(float minx, float miny, float maxx, float maxy, float originX, float originY)
	{
		mWorldXMin = minx;
		mWorldYMin = miny;
		mWorldXMax = maxx;
		mWorldYMax = maxy;
		
		mOriginX = originX;
		mOriginY = originY;
	}
	
	/**
	 * Update the dimensions of the world using offset values.
	 * 
	 * @param offsetx
	 * @param offsety
	 */
	public void updateWorldDimensionsByOffset(float offsetx, float offsety)
	{
		mWorldXMin += offsetx;
		mWorldYMin += offsety;
		mWorldXMax += offsetx;
		mWorldYMax += offsety;
		
		mOriginX += offsetx;
		mOriginY += offsety;
	}
	
	/**
	 * Get origin.
	 * @return
	 */
	public Point2DFloat getWorldOrigin()
	{
		Point2DFloat origin = new Point2DFloat();
		origin.mX = mOriginX;
		origin.mY = mOriginY;
		
		return origin;
	}
	
	/**
	 * Get dimensions of view.
	 * 
	 * @return
	 */
	public RectInt getViewDimensions()
	{
		RectInt rf = new RectInt();
		rf.left = mViewXMin;
		rf.top = mViewYMin;
		rf.right = mViewXMax;
		rf.bottom = mViewYMax;
		
		return rf;
	}
	
	/**
	 * Update dimensions of view using absolute values.
	 * 
	 * @param minx
	 * @param miny
	 * @param maxx
	 * @param maxy
	 */
	public void updateViewDimensions(int minx, int miny, int maxx, int maxy)
	{
		mViewXMin = minx;
		mViewYMin = miny;
		mViewXMax = maxx;
		mViewYMax = maxy;
	}
	
	/**
	 * Update dimensions of view using absolute values.
	 * Also update values of padding.
	 * 
	 * @param minx
	 * @param miny
	 * @param maxx
	 * @param maxy
	 * @param leftPadding
	 * @param topPadding
	 * @param rightPadding
	 * @param bottomPadding
	 */
	public void updateViewDimensions(int minx, int miny, int maxx, int maxy, int leftPadding, int topPadding, int rightPadding, int bottomPadding)
	{
		mViewXMin = minx + leftPadding;
		mViewYMin = miny + topPadding;
		mViewXMax = maxx - rightPadding;
		mViewYMax = maxy - bottomPadding;
	}
	
	/**
	 * Update dimensions of view using offset values.
	 * @param offsetx
	 * @param offsety
	 */
	public void updateViewDimensionsByOffset(int offsetx, int offsety)
	{
		mViewXMin += offsetx;
		mViewYMin += offsety;
		mViewXMax += offsetx;
		mViewYMax += offsety;
	}
	
	/**
	 * Convert x coordinate value in world to view.
	 * @param worldX
	 * @return
	 */
	public abstract int convertToViewX(double worldX);
	
	/**
	 * Convert y coordinate value in world to view.
	 * @param worldX
	 * @return
	 */
	public abstract int convertToViewY(double worldY);
	
	/**
	 * Convert x and y coordinate value in world to view.
	 * @param worldX
	 * @return
	 */
	public abstract Point2DInt convertToView(double worldX, double worldY);
	
	/**
	 * Convert 2d point value in world to view.
	 * @param worldX
	 * @return
	 */
	public abstract Point2DInt convertToView(Point2DFloat pt);
	
	/**
	 * Convert rectangle value in world to view.
	 * @param worldX
	 * @return
	 */
	public abstract RectInt convertToView(RectFloat world);
	
	/**
	 * Convert x coordinate value in view to world.
	 * @param viewX
	 * @return
	 */
	public abstract float convertToWorldX(int viewX);
	
	/**
	 * Convert y coordinate value in view to world.
	 * @param viewX
	 * @return
	 */
	public abstract float convertToWorldY(int viewY);
	
	/**
	 * Convert 2d point value in view to world.
	 * @param viewX
	 * @return
	 */
	public abstract Point2DFloat convertToWorld(int viewX, int viewY);
	
	/**
	 * Convert 2d coordinate value in view to world.
	 * @param viewX
	 * @return
	 */
	public abstract Point2DFloat convertToWorld(Point2DInt pt);
}

/* end */
